package com.wyzt.order.utils;

import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.wyzt.common.enums.ExceptionEnum;
import com.wyzt.common.exception.WyztException;
import com.wyzt.order.config.PayConfig;
import com.wyzt.order.enums.OrderStatusEnum;
import com.wyzt.order.mapper.OrderMapper;
import com.wyzt.order.mapper.OrderStatusMapper;
import com.wyzt.order.pojo.Order;
import com.wyzt.order.pojo.OrderStatus;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.github.wxpay.sdk.WXPayConstants.FAIL;
import static com.github.wxpay.sdk.WXPayConstants.SUCCESS;

@Component
@Slf4j
public class PayHelper {

    @Autowired
    private WXPay wxPay;
    @Autowired
    protected PayConfig config;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderStatusMapper orderStatusMapper;

    /**
     * 返回url地址
     *
     * @param orderId
     * @param totalPay
     * @param desc
     * @return
     */
    public String createPayUrl(Long orderId, Long totalPay, String desc) {
        try {
            Map<String, String> data = new HashMap<>();
            // 商品描述
            data.put("body", desc);
            // 订单号
            data.put("out_trade_no", orderId.toString());
            //金额，单位是分
            data.put("total_fee", totalPay.toString());
            //调用微信支付的终端IP（estore商城的IP）
            data.put("spbill_create_ip", "127.0.0.1");
            //回调地址
            data.put("notify_url", config.getNotifyUrl());
            // 交易类型为扫码支付
            data.put("trade_type", "NATIVE");

            //利用wxpay工具，完成下单
            Map<String, String> result = this.wxPay.unifiedOrder(data);
            //判断通信、业务标识
            isSuccess(result);
            //下单成功，获取支付链接
            return result.get("code_url");
        } catch (Exception e) {
            log.error("[微信下单]订单异常", e);
            throw new WyztException(ExceptionEnum.WX_PAY_ORDER_FAIL);
        }
    }

    public PayState queryOrder(Long orderId) {
        Map<String, String> data = new HashMap<>();
        // 订单号
        data.put("out_trade_no", orderId.toString());
        try {
            Map<String, String> result = this.wxPay.orderQuery(data);
            //校验状态
            isSuccess(result);
            //校验签名
            isValidSign(result);
            //校验金额
            String totalFeeStr = result.get("total_fee");
            String tradeNoStr = result.get("out_trade_no");
            if (StringUtils.isEmpty(totalFeeStr)) {
                throw new WyztException(ExceptionEnum.INVALID_SIGN_PARAM);
            }
            if (StringUtils.isEmpty(tradeNoStr)) {
                throw new WyztException(ExceptionEnum.INVALID_SIGN_PARAM);
            }
            //获取结果中的金额
            Long totalFee = Long.valueOf(totalFeeStr);
            Order order = orderMapper.selectByPrimaryKey(orderId);
            if (!totalFee.equals(order.getActualPay())) {
                throw new WyztException(ExceptionEnum.INVALID_SIGN_PARAM);
            }

            //查询状态
            String tradeState = result.get("trade_state");
            if (SUCCESS.equals(tradeState)) {
                //修改订单状态
                OrderStatus orderStatus = new OrderStatus();
                orderStatus.setStatus(OrderStatusEnum.PAYED.value());
                orderStatus.setOrderId(orderId);
                orderStatus.setPaymentTime(new Date());
                int count = orderStatusMapper.updateByPrimaryKeySelective(orderStatus);
                if (count != 1) {
                    throw new WyztException(ExceptionEnum.UPDATE_STATUS_ERROR);
                }
                //返回成功
                return PayState.SUCCESS;
            }
            if (StringUtils.equals("USERPAYING", tradeState)
                    || StringUtils.equals("NOTPAY", tradeState)) {
                return PayState.NOT_PAY;
            }
            return PayState.FAIL;

        } catch (Exception e) {
            log.error("查询订单状态异常", e);
            return PayState.NOT_PAY;
        }
    }

    public void isSuccess(Map<String, String> result) {
        if (FAIL.equals(result.get("return_code"))) {
            //通信失败
            log.error("[微信下单]创建预交易订单失败，错误信息：{}", result.get("return_msg"));
            throw new WyztException(ExceptionEnum.WX_PAY_ORDER_FAIL);
        }
        if (FAIL.equals(result.get("result_code"))) {
            //下单失败
            log.error("[微信下单]下单订单失败，错误信息：{}", result.get("err_code_des"));
            throw new WyztException(ExceptionEnum.WX_PAY_ORDER_FAIL);
        }
    }

    /**
     * 校验签名
     *
     * @param result
     */
    public void isValidSign(Map<String, String> result) {
        try {
            //重新生成签名，和传过来的签名进行比较
            String sign1 = WXPayUtil.generateSignature
                    (result, config.getKey(), WXPayConstants.SignType.HMACSHA256);
            String sign2 = WXPayUtil.generateSignature
                    (result, config.getKey(), WXPayConstants.SignType.MD5);

            String sign = result.get("sign");
            if (StringUtils.equals(sign, sign1) && StringUtils.equals(sign, sign2)) {
                //签名有误，抛出异常
                throw new WyztException(ExceptionEnum.INVALID_SIGN_ERROR);
            }
        } catch (Exception e) {
            throw new WyztException(ExceptionEnum.INVALID_SIGN_ERROR);
        }
    }
}
